//------------------------------------------TESTBENCH---------------------
`timescale 1ps/1ps
module pwmbus_tb();

	event lsy;
	parameter CLK_CON=8'h00;		// register's address
	parameter CNT_CON=8'h01;		
	parameter CP_CON_0=8'h02;	
	parameter CP_CON_1=8'h03;
	parameter CP_CON_2=8'h04;
	parameter CP_CON_3=8'h05;

	parameter COUNT_H=8'h06;
	parameter COUNT_L=8'h07;
	parameter COMP0_H=8'h08;
	parameter COMP0_L=8'h09;
	parameter COMP1_H=8'h0A;
	parameter COMP1_L=8'h0B;
	parameter COMP2_H=8'h0C;
	parameter COMP2_L=8'h0D;
	parameter COMP3_H=8'h0E;
	parameter COMP3_L=8'h0F;
	parameter INTF	 =8'h10;

	reg 		  clk;
	reg			  rst;
	reg			  cs;
	reg 		  rd;
	reg 		  wr;
	reg		[7:0] write_addr;	
	reg		[7:0] read_addr;
	reg		[7:0] data_in;

	wire	[7:0] data_out;
	wire		  pwmout_0;
	wire		  pwmout_1;
	wire		  pwmout_2;
	wire		  pwmout_3;
	wire		  irq;

	reg 	[7:0] temp_data;
	
	initial clk=0;
	always #5 clk=~clk;			

	pwm PWM_TOP 
	(	.clk(clk),
		.rst(rst),
		.cs(cs),
		.rd(rd),
		.wr(wr),
		.write_addr(write_addr),
		.read_addr(read_addr),
		.data_in(data_in),
		.data_out(data_out),
		.pwmout_0(pwmout_0),
		.pwmout_1(pwmout_1),
		.pwmout_2(pwmout_2),
		.pwmout_3(pwmout_3),
		.irq(irq)
	);

	initial
	begin
		wr = 0;
		rd = 0;
		cs = 0;
		rst = 0;
		read_addr = 0;
		write_addr = 0;
		data_in = 0;

		#10;
		rst = 1;
		#10;
		rst = 0;

		write_register(COMP0_L,8'h20);
		write_register(COMP0_H,8'H40);
		write_register(COMP1_L,8'h20);
		write_register(COMP1_H,8'h40);
		write_register(COMP2_L,8'h20);
		write_register(COMP2_H,8'h40);
		write_register(COMP3_H,8'h40);
		write_register(COMP3_L,8'h20);

		write_register(CLK_CON,8'h0); 
		write_register(CP_CON_0,8'b10001000);	//enable,edge,no_reload,enable irq,pol=0; 
		write_register(CP_CON_1,8'b10101000);	//enable,edge,reload,enable irq,pol=0;	
		write_register(CP_CON_2,8'b11001000);	//enable,center,no_reload,enable irq, pol=0;
		write_register(CP_CON_3,8'b11101000);	//enable,center,reload,enable_irq,pol=0;


		write_register(CNT_CON,8'b11000000);	//enable counter
		#400000;
		read_register(INTF,temp_data);
		#20000;
		read_register(COUNT_L,temp_data);
		#1;
		read_register(COUNT_H,temp_data);
		#10000000;
		$stop;
	end

	initial									//test reload
	begin
		#2707997;
		->lsy;
		write_register(COMP0_L,8'h80);
		write_register(COMP0_H,8'H80);
		write_register(COMP1_L,8'h80);
		write_register(COMP1_H,8'h80);
		write_register(COMP2_L,8'h80);
		write_register(COMP2_H,8'h80);
		write_register(COMP3_H,8'h80);
		write_register(COMP3_L,8'h80);

	end

	initial								//test reload and check flitch
	begin
		#4279736;
		->lsy;
		write_register(COMP0_L,8'h90);
		write_register(COMP0_H,8'H90);
		write_register(COMP1_L,8'h90);
		write_register(COMP1_H,8'h90);
		write_register(COMP2_L,8'h90);
		write_register(COMP2_H,8'h90);
		write_register(COMP3_H,8'h90);
		write_register(COMP3_L,8'h90);

	end

	initial			//test polarity
	begin
		#6060976;
		->lsy;
		write_register(CP_CON_0,8'b10001100);	//enable,edge,no_reload,enable irq,pol=0; 
		write_register(CP_CON_1,8'b10101100);	//enable,edge,reload,enable irq,pol=0;	
		write_register(CP_CON_2,8'b11001100);	//enable,center,no_reload,enable irq, pol=0;
		write_register(CP_CON_3,8'b11101100);	//enable,center,reload,enable_irq,pol=0;
	end

	initial
	begin
		#7072516;
		->lsy;
		write_register(COMP0_L,8'hFF);
		write_register(COMP0_H,8'HFF);
		write_register(COMP1_L,8'hFF);
		write_register(COMP1_H,8'hFF);
		write_register(COMP2_L,8'hFF);
		write_register(COMP2_H,8'hFF);
		write_register(COMP3_H,8'hFF);
		write_register(COMP3_L,8'hFF);
	end


	task write_register;
		input [7:0] addr;
		input [7:0] data;
		
		begin 
			@ (posedge clk);
			#1;
			cs = 1;
			wr = 1;
			write_addr = addr;
			data_in = data;
			@ (posedge clk);
			#1;
			cs = 0;
			wr = 0;
			write_addr = 8'h0;
			data_in = 8'h0;
		end
	endtask

	task read_register;
		input [7:0] addr;
		output [7:0] data;

		begin
			@ (posedge clk);
			#1;
			cs = 1;
			rd = 1;
			read_addr = addr;
			data = data_out;
			@ (posedge clk);
			#1;
			cs = 0;
			rd = 0;
			read_addr = 8'h0;
		end
	endtask
			

endmodule
